package org.gitee.simpleutil.core.excel;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class ExcelTool {

    public static final Logger logger = LoggerFactory.getLogger(ExcelTool.class);
    private static CountDownLatch countDownLatch = new CountDownLatch(0);

    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws Exception {
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }

    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws Exception {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws Exception {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new Exception(e.getMessage());
        }
    }

    /***
     * 创建压缩文件
     * @param folderPath
     * @param outPath
     * @return
     */
    public static String getZipPath(String folderPath, String outPath) {
        ZipUtil.zip(folderPath);
        String zipPath = outPath + DateUtil.today() + ".zip";
        // 删除原文件夹,避免占用多余空间
        if (FileUtil.exist(zipPath)) {
            FileUtil.del(folderPath);
        }
        return zipPath;
    }

    /**
     * excel通用导出
     *
     * @author lihonglin
     * @date 2023/3/15 14:47
     */
    public static void writeToResponse(HttpServletResponse response, long startTime, String zipPath) {
        try (ServletOutputStream out = response.getOutputStream()) {
            response.setContentType("application/octet-stream");
            //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
            response.setHeader("Content-Disposition", "attachment;filename=" + "diffinfo" + DateUtil.now() + ".zip");
            out.write(file2buf(new File(zipPath)));
            out.flush();
            logger.info("导出完成,耗时:{}ms", System.currentTimeMillis() - startTime);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (FileUtil.exist(zipPath)) {
                FileUtil.del(zipPath);
            }
        }
    }

    /**
     * 文件转字节数组
     *
     * @param fobj
     * @return
     */
    public static byte[] file2buf(File fobj) {
        byte[] buffer = null;
        try {
            if (!fobj.exists()) {
                return null;
            }
            FileInputStream fis = new FileInputStream(fobj);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = fis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    private static <T> void excelPool(HttpServletResponse response, T clazz, String path, BaseMapper<T> mapper) throws Exception {
//        long startTime = System.currentTimeMillis();
//        LambdaQueryWrapper<T> eq = new LambdaQueryWrapper<>();
//        //总页数
//        int total = mapper.selectCount(eq);
//        final int pageSize = 50000;
//        int maxPage = total / pageSize + 1;
//        if ((countDownLatch.getCount() > 0)) {
//            throw new Exception("有任务正在进行中......");
//        }
//        ThreadPool config = new ThreadPool();
//        ThreadPoolTaskExecutor executor = config.taskExecutor();
//        countDownLatch = new CountDownLatch(maxPage);
//        //存放地址
//        final String folderPath = path + DateUtil.today() + File.separator;
//        IPage iPage = new Page();
//        for (int i = 0; i < maxPage; i++) {
//            final int currPage = i;
//            String filePath = folderPath + "batchOriginData" + currPage + ".xlsx";
//            final ExcelWriter excelWriter = EasyExcel.write(filePath, clazz.getClass()).build();
//            executor.execute(() -> {
//                try {
//                    iPage.setCurrent(currPage);
//                    iPage.setSize(pageSize);
//                    IPage page = mapper.selectPage(iPage, eq);
//                    List<T> list = page.getRecords();
//                    if (CollectionUtil.isNotEmpty(list)) {
//                        logger.info("查询页数:{},查询总耗时:{}ms", currPage, System.currentTimeMillis() - startTime);
//                        WriteSheet writeSheet = EasyExcel.writerSheet(currPage, "工作表" + currPage).build();
//                        excelWriter.write(list, writeSheet);
//                        logger.info("sheet{}页已写入,总页数{}", currPage, maxPage);
//                        excelWriter.finish();
//                    }
//                } catch (Exception e) {
//                    logger.error(e.getMessage(), e);
//                } finally {
//                    countDownLatch.countDown();
//                }
//            });
//        }
//        //线程任务阻塞
//        PoolTool.countDownLatchAwait(countDownLatch);
//        //创建压缩包文件并导出文件
//        ExcelTool.writeToResponse(response, startTime, ExcelTool.getZipPath(folderPath, path));
    }

}
